﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace SPVSX.Explorer.Extensions.NodeInformation
{
    /// <summary>
    /// Contains basic data about a single content type on the SharePoint site. This class is 
    /// serializable so that instances of it can be sent between the SPVSX.Explorer.Extensions and 
    /// SPVSX.Explorer.Commands assemblies.
    /// </summary>
    [Serializable]
    class ContentTypeNodeInfo
    {
        #region Properties

        /// <summary>
        /// Gets or set the  content type ID of the content type.
        /// </summary>
        public string Id
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the content type name.
        /// </summary>
        public string Name
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the content type group to which the content type is assigned. 
        /// Content type groups are user-defined groups that help you organize your columns into logical categories.
        /// </summary>
        public string Group
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the read only value, TRUE to define the content type as read-only. 
        /// If you do not include this attribute, SharePoint Foundation treats 
        /// the content type as if this attributes was set to FALSE.
        /// </summary>
        public bool? ReadOnly
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the hidden value, TRUE to define the content type as hidden. 
        /// If you define a content type as hidden, SharePoint Foundation does not display 
        /// that content type on the New button in list views. 
        /// If you do not include this attribute, SharePoint Foundation treats the content 
        /// type as if this attributes was set to FALSE.
        /// </summary>
        public bool? Hidden
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the description for the content type, to display in the SharePoint Foundation user interface.
        /// </summary>
        public string Description
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the sealed value, TRUE to define the content type as sealed. You must have site collection 
        /// administrator rights to unseal and edit a content type defined as sealed. 
        /// If you do not include this attribute, SharePoint Foundation treats the content type as if this attributes
        /// was set to FALSE.
        /// </summary>
        public bool? Sealed
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the ID of the feature in which the content type is packaged.
        /// </summary>
        public string FeatureId
        {
            get;
            set;
        }

        public FieldRef[] FieldRefs
        {
            get;
            set;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Construct the xml for the Content Type
        /// </summary>
        /// <returns>The xml</returns>
        XElement BuildEntireElement()
        {
            XElement contentType = new XElement("ContentType");

            if (!String.IsNullOrEmpty(Id))
            {
                XAttribute id = new XAttribute("ID", Id);
                contentType.Add(id);
            }

            if (!String.IsNullOrEmpty(Name))
            {
                XAttribute name = new XAttribute("Name", Name);
                contentType.Add(name);
            }

            if (!String.IsNullOrEmpty(Description))
            {
                XAttribute description = new XAttribute("Description", Description);
                contentType.Add(description);
            }

            if (!String.IsNullOrEmpty(Group))
            {
                XAttribute group = new XAttribute("Group", Group);
                contentType.Add(group);
            }

            if (!String.IsNullOrEmpty(FeatureId))
            {
                XAttribute featureId = new XAttribute("FeatureId", FeatureId);
                contentType.Add(featureId);
            }

            if (Hidden != null)
            {
                XAttribute hidden = new XAttribute("Hidden", Hidden);
                contentType.Add(hidden);
            }

            if (ReadOnly != null)
            {
                XAttribute readOnly = new XAttribute("ReadOnly", ReadOnly);
                contentType.Add(readOnly);
            }

            if (Sealed != null)
            {
                XAttribute sealedValue = new XAttribute("Sealed", Sealed);
                contentType.Add(sealedValue);
            }

            XElement fieldRefs = new XElement("FieldRefs");

            foreach (var item in FieldRefs)
            {
                fieldRefs.Add(new XElement("FieldRef", new XAttribute("ID", item.Id), new XAttribute("Name", item.Name)));
            }

            contentType.Add(fieldRefs);


            return contentType;
        }

        /// <summary>
        /// ToString returns the xml representation of the element
        /// </summary>
        /// <returns>The xml</returns>
        public override string ToString()
        {
            return BuildEntireElement().ToString().Replace(@" xmlns=""""", "");
        }

        #endregion

        [Serializable]
        public class FieldRef
        {
            /// <summary>
            /// Gets or sets the ID of the field.
            /// </summary>
            public string Id
            {
                get;
                set;
            }

            /// <summary>
            /// Gets or sets the name of the field.
            /// </summary>
            public string Name
            {
                get;
                set;
            }            
        }
    }
}
